// ViafirmaClientExample.cpp : Defines the entry point for the console application.
//

//#define _CRTDBG_MAP_ALLOC
//#include <stdlib.h>
//#include <crtdbg.h>

#include <stdlib.h>
#include<time.h>

#include "stdafx.h"
#include "includes\viafirmaClient.h"
#include <string>


#include <iostream>
#include <fstream>


void printExampleANSIX9(SignedDocument * info);

/**
 * Load file into byte array (for test)
 */
int load_file_to_memory(const char *filename, unsigned char **result) 
{ 
	int size = 0;
	FILE *f = fopen(filename, "rb");
	if (f == NULL) 
	{ 
		*result = NULL;
		return -1; // -1 means file opening fail 
	} 
	fseek(f, 0, SEEK_END);
	size = ftell(f);
	fseek(f, 0, SEEK_SET);
	*result = (unsigned char *)malloc(size+1);
	if (size != fread(*result, sizeof(char), size, f)) 
	{ 
		free(*result);
		return -2; // -2 means file reading fail 
	} 
	fclose(f);
	(*result)[size] = 0;
	return size;
}




/**
 * Example of Viafirma:
 *  0.- Configuration
 *  1.- Method ping (test connection)
 *  2.- Sign
 *  3.- get info.
 */
int exampleFull(){
	try{
		//************************
		// Configuration
		//**************************
		//std::string urlViafirma("http://testservices.viafirma.com/viafirma");
		//std::string urlViafirma("http://pc160.viavansi.com/viafirma-business");

		//std::string urlViafirma("http://192.168.10.62:8080/viafirma-business");
		std::string urlViafirma("http://192.168.1.141:7080/viafirma-business");

		// create instance of Viafirma client (dont share between threads)
		viafirmaClient v(urlViafirma);


		//***************
		// Test connection method
		//***************

		try{
			std::string msg("message test");
			std::string result=v.ping(msg);
			std::cout << "TEST ping method. Result:"<<result;
		}catch(char * message){
			 printf( "\n Exception: %s\n", message );
			 return -1;
		}



	
		//***************
		// Test Sign document (CMD/PKCS7 format)
		//***************

		std::string nameFile("test.png"); //anything name.
		// Load data to sign (somewhere, for example one image file)
		// Example load file
		unsigned char * dataToSign ;	
		int dataSize=load_file_to_memory("test.png",&dataToSign);

		// alias and pass of certificate.
		std::string alias("xnoccio");
		std::string password("12345");

		try{
			// Call to server (send to server the original document)
			//std::string codSign=v.signByServer(nameFile,dataToSign,dataSize,alias,password,TYPE_FILE_BINARRY,TYPE_FORMAT_SIGN_BINARRY);

			// Call to server (compute sha1 and sent to server only raw sha1)
			std::string codSign=v.signByServerWithSha1(nameFile,dataToSign,dataSize,alias,password,TYPE_FORMAT_SIGN_BINARRY);
			std::cout << "TEST Sign method. Id sign:"<<codSign;
			std::cout<<"\nYou can see the verification info in:\n "<<urlViafirma<<"/v/"+codSign;
	


			//***************
			// get signed Document (CMD/PKCS7 format)
			//***************

			SignedDocument * info=v.getSignedDocument(codSign);
			// Signed Document Data: CMD/PKCS7 data: info.data;
			std::cout<<"\n id:"<<info->id;

			//std::cout<<"\n Signed Document:"<<info.data;
			std::cout<<"\n Signed Document size:"<<info->dataLen;

			std::ofstream output;
			output.open("out.p7s",std::ios::binary);
			output.write(info->data,info->dataLen);
			output.flush();
			output.close();


			// Example ANSI X9.100-180-2006
			printExampleANSIX9(info);


			unsigned char * signedDocument=(unsigned char*)info->data;
			int signdDocumentSize=info->dataLen;
			// Examble validation data with SHA1
			bool validationOK=v.validateWithSha1(dataToSign,dataSize,signedDocument,signdDocumentSize,TYPE_FORMAT_SIGN_BINARRY);
			std::cout<<"\n Validation:"<<validationOK;



			//	Full validation
			validationOK=v.checkOrignalVSSignedDocument(dataToSign,dataSize,signedDocument,signdDocumentSize,TYPE_FORMAT_SIGN_BINARRY);
			std::cout<<"\n Full Validation:"<<validationOK;




			delete info;
			delete dataToSign;

			
		}catch(char * message){
			 printf( "\n Exception: %s\n", message );
			 return -1;
		}



	}catch(char * msg){
		std::cout<<"\nException:"<<msg;
	}



	return 0;
}



int exampleSimple(){
	try{
		//************************
		// Configuration
		//**************************
		//std::string urlViafirma("http://pc160.viavansi.com/viafirma-business");
		std::string urlViafirma("http://testservices.viafirma.com/viafirma");
			_CrtDumpMemoryLeaks();
		// create instance of Viafirma client (dont share between threads)
		viafirmaClient v(urlViafirma);

			_CrtDumpMemoryLeaks();

	
		//***************
		// Test Sign document (CMD/PKCS7 format)
		//***************

		std::string nameFile("test.png"); //anything name.
		// Load data to sign (somewhere, for example one image file)
		// Example load file
		unsigned char * dataToSign ;	
		int dataSize=load_file_to_memory("test.png",&dataToSign);

		// alias and pass of certificate.
		std::string alias("xnoccio");
		std::string password("12345");

		try{
			// Call to server (compute sha1 and sent to server only raw sha1)
			std::string codSign=v.signByServerWithSha1(nameFile,dataToSign,dataSize,alias,password,TYPE_FORMAT_SIGN_BINARRY);
			std::cout << "TEST Sign method. Id sign:"<<codSign;
			std::cout<<"\nYou can see the verification info in:\n "<<urlViafirma<<"/v/"+codSign;

			delete dataToSign;

			
		}catch(char * message){
			 printf( "\n Exception: %s\n", message );
			 return -1;
		}

		delete & v;

	}catch(char * msg){
		std::cout<<"\nException:"<<msg;
	}



	_CrtDumpMemoryLeaks();

	return 0;
}


int _tmain(int argc, _TCHAR* argv[])
{

	int timeStart=clock();
	for(int i=0;i<100;i++){
		//exampleSimple();
		exampleFull();
		_CrtDumpMemoryLeaks();
	}
	int timeEnd=clock();
	std::cout<<"\n Time:"<<(timeEnd-timeStart)<<" ms";

	// wait;
	std::string temp;
	std::cin>>temp;
}



void printExampleANSIX9(SignedDocument * info){
	std::cout<<"\n\n****************************\n";
	std::cout<<"Example ANSI X9.100-180-2006\n";
	//22.24 Digital Certificate Issuer Distinguished Name
	std::cout<<"22.24 Digital Certificate Issuer Distinguished Name\n";
	std::cout<<"\t"<<info->issuerDN<<"\n";

	//22.25 Digital Certificate Serial Number
	std::cout<<"22.25 Digital Certificate Serial Number\n";
	std::cout<<"\t"<<info->serialNumber<<"\n";

	//22.26 Digital Certificate
	std::cout<<"22.26 Digital Certificate\n";
	std::cout<<"\t"<<info->X509<<"\n";
	
	
	//21.11 Digital Signature Hash Function Method
	// 0 SHA-1
	// 4 SHA-512
	std::cout<<"21.11 Digital Signature Hash Function Method\n";
	std::cout<<"\t"<<"0"<<"\n";

	//21.12 Digital Signature Cryptographic Algorithm Method
	// 1 RSA
	// 2 Elliptic Curve DSA
	std::cout<<"21.12 Digital Signature Cryptographic Algorithm Method\n";
	std::cout<<"\t"<<"1"<<"\n";

	//21.13 DSA/RSA Key Size or ECC Curve Number
	std::cout<<"21.13 DSA/RSA Key Size or ECC Curve Number\n";
	std::cout<<"\t"<<info->rsaKeySize<<"\n";
	
	//21.15 Digital Certificate Format
	// 1 X.509 certificate PKCS7
	std::cout<<"21.15 Digital Certificate Format\n";
	std::cout<<"\t"<<"1"<<"\n";


	//27.2 Digital Certificate Format
	std::cout<<"27.2 Digital Certificate Format\n";
	std::cout<<"\t"<<"1"<<"\n";

	//27.3 Length of Digital Certificate Issuer Distinguished Name
	std::cout<<"27.3 Length of Digital Certificate Issuer Distinguished Name\n";
	std::cout<<"\t"<<info->issuerDN.length()<<"\n";


	//27.4 Length of Digital Certificate Serial Number
	std::cout<<"27.4 Length of Digital Certificate Serial Number\n";
	std::cout<<"\t"<<info->serialNumber.length()<<"\n";

	
	//27.5 Length of X.509 Digital Certificate
	std::cout<<"27.5 Length of X.509 Digital Certificate\n";
	std::cout<<"\t"<<info->X509Len<<"\n";

	//27.6 Digital Certificate Issuer Distinguished Name
	std::cout<<"27.6 Digital Certificate Issuer Distinguished Name\n";
	std::cout<<"\t"<<info->issuerDN.length()<<"\n";

	
	//27.7 Digital Certificate Serial Number
	std::cout<<"27.7 Digital Certificate Serial Number\n";
	std::cout<<"\t"<<info->serialNumber<<"\n";

	//27.7 Digital Certificate Serial Number
	std::cout<<"27.8 X.509 Digital Certificate";
	std::cout<<"\t"<<info->X509<<"\n";

	std::cout<<"****************************\n";

}